<template>
  <div class="vue-quill-editor">
    <el-upload
      style="display: none"
      class="quill-image-uploader"
      action="/"
      :show-file-list="false"
      :accept="_accept"
      :before-upload="handleBeforeunload"
      :http-request="handleHttpRequest"
    />

    <quill-editor
      ref="quillEditor"
      v-model="_content"
      :options="_options"
      :disabled="disabled"
    />
  </div>
</template>

<script>
// * 上传接口
import { upload } from '@/api/common'
// * 鉴权方法
import { getToken } from '@/utils/auth'

export default {
  name: 'VueQuillEditor',
  components: {},
  props: {
    disabled: {
      type: Boolean,
      default: false,
    },
    businessType: {
      type: [String, Number],
      required: true,
    },
    content: {
      type: String,
      default: '',
    },
    options: {
      type: Object,
      default: () => ({
        modules: {
          toolbar: {
            container: [
              [{ font: [] }],
              [{ size: ['small', false, 'large', 'huge'] }],
              [{ header: [1, 2, 3, 4, 5, 6, false] }],
              [
                { header: 1 },
                { header: 2 },
                'bold',
                'italic',
                'underline',
                'strike',
                { script: 'sub' },
                { script: 'super' },
                { list: 'bullet' },
                { list: 'ordered' },
                { indent: '-1' },
                { indent: '+1' },
                { align: [] },
                'image',
              ],
            ],
            handlers: {
              // 自定义图片上传
              image: function(value) {
                if (value) {
                  document.querySelector('.quill-image-uploader input').click()
                } else {
                  this.quill.format('image', false)
                }
              },
            },
          },
        },
      }),
    },
    accepts: {
      type: Array,
      default: () => ['image/png', 'image/jpeg', 'image/jpg'],
    },
    limitSize: {
      type: Number,
      default: 50,
    },
  },
  data() {
    return {
      // * 设置上传的请求头部
      headers: { Authorization: 'Bearer ' + getToken() },
    }
  },
  computed: {
    _content: {
      get() {
        return this.content
      },
      set(val) {
        this.$emit('update:content', val)
      },
    },
    _accept: {
      get() {
        let accepts = [...this.accepts]
        accepts.forEach((item) => item.trim())
        return accepts.join(',')
      },
    },
    _options: {
      get() {
        return { placeholder: '请输入文本...', theme: 'snow', ...this.options }
      },
    },
  },
  methods: {
    handleBeforeunload(file) {
      const accepts = ['image/png', 'image/jpeg', 'image/jpg']

      const isType = accepts.includes(file.type)
      const isLt = file.size < this.limitSize * 1024 * 1024

      if (!isLt) {
        this.$message.error('上传图片大小不能超过 50 MB！')
        return false
      }

      return isType && isLt
    },
    handleHttpRequest(e) {
      const loading = this.$loading({
        lock: true,
        text: '上传中...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })

      let formData = new FormData()
      formData.append('file', e.file)
      formData.append('businessType', this.businessType)

      upload(formData)
        .then((response) => {
          let { data } = response
          let { filePath } = data

          let quill = this.$refs['quillEditor'].quill

          let length = quill.getSelection().index
          quill.insertEmbed(
            length,
            'image',
            process.env['VUE_APP_BASE_API'] + filePath
          )
          quill.setSelection(length + 1)

          loading.close()
        })
        .catch(() => {
          loading.close()
        })
    },
  },
}
</script>

<style lang="scss">
.quill-editor {
  height: 200px !important;
  width: 1000px;
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: '14px';
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='small']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='small']::before {
  content: '10px';
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='large']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='large']::before {
  content: '18px';
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value='huge']::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value='huge']::before {
  content: '32px';
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: '文本';
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='1']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='1']::before {
  content: '标题1';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='2']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='2']::before {
  content: '标题2';
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='3']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='3']::before {
  content: '标题3';
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='4']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='4']::before {
  content: '标题4';
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='5']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='5']::before {
  content: '标题5';
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value='6']::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value='6']::before {
  content: '标题6';
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: '标准字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='serif']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='serif']::before {
  content: '衬线字体';
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value='monospace']::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value='monospace']::before {
  content: '等宽字体';
}
</style>
